unit PropertyBox;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ExtCtrls, StdCtrls, DEnvyControls;
const
  fieldheight = 16;
type
  TPropType = (ptString,ptNumber,ptBoolean,ptColor,ptButton,ptCombobox);


  TMPanel = class(TPanel)
  private
    { Private declarations }
    FItems:TStringList;
    FTypes:TStringList;
    FValues:TStringList;
    oldindex:integer;
    currindex:integer;
    edit:TDETextBox;
  protected
    { Protected declarations }
    procedure  Paint; override;
    procedure DrawItem(i:integer;state:integer);
  public
    { Public declarations }
    property Canvas;

    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
    procedure AddProperty(pname:string;ptype:tproptype;value:string);
    function GetPropertyValue(pname:string):string;
    procedure InsertProperty(item:integer;pname:string;ptype:tproptype;value:string);
    procedure ClearPropertyes;
    procedure MouseDown(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer); override;
    procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
    procedure MouseUp(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer); override;
  published
    { Published declarations }
  end;

  TPropertyBox = class(TScrollBox)
  private
    { Private declarations }
    FMainPanel:TMPanel;
  protected
    { Protected declarations }
  public
    { Public declarations }
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    { Published declarations }
    procedure InsertProperty(item:integer;pname:string;ptype:tproptype;value:string);virtual;
    procedure AddProperty(pname:string;ptype:tproptype;value:string);virtual;
    function GetPropertyValue(pname:string):string;virtual;
    procedure ClearPropertyes;virtual;
  end;

procedure Register;
function ptypetostr(ptype:TPropType):string;
function strtoptype(s:string):TPropType;

implementation
function ptypetostr(ptype:TPropType):string;
begin
  case ptype of
  ptString:Result:='ptString';
  ptNumber:Result:='ptNumber';
  ptBoolean:Result:='ptBoolean';
  ptColor:Result:='ptColor';
  ptButton:Result:='ptButton';
  ptCombobox:Result:='ptCombobox';
  end;
end;

function strtoptype(s:string):TPropType;
begin
  if s='ptString' then Result:=ptString;
  if s='ptNumber' then Result:=ptNumber;
  if s='ptBoolean' then Result:=ptBoolean;
  if s='ptColor' then Result:=ptColor;
  if s='ptButton' then Result:=ptButton;
  if s='ptCombobox' then Result:=ptCombobox;
end;

constructor TPropertyBox.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FMainPanel:=TMPanel.Create(self);
  FMainPanel.Parent:=self;
//  FMainPanel.AddProperty('Prop 1',ptString,'0');
//  FMainPanel.AddProperty('Prop 2',ptString,'0');
//  FMainPanel.AddProperty('Prop 3',ptString,'0');
//  FMainPanel.AddProperty('Prop 4',ptString,'0');
//  FMainPanel.AddProperty('Prop 5',ptString,'0');
//  FMainPanel.Repaint;
end;
destructor TPropertyBox.Destroy;
begin
  FMainPanel.Free;
  inherited Destroy;
end;

procedure TPropertyBox.InsertProperty(item:integer;pname:string;ptype:tproptype;value:string);
begin
  FMainPanel.InsertProperty(item,pname,ptype,value);
end;

procedure TPropertyBox.AddProperty(pname:string;ptype:tproptype;value:string);
begin
  FMainPanel.AddProperty(pname,ptype,value);
end;

function TPropertyBox.GetPropertyValue(pname:string):string;
var i:integer;
begin
  Result:=FMainPanel.GetPropertyValue(pname);
end;

procedure TPropertyBox.ClearPropertyes;
begin
  FMainPanel.ClearPropertyes;
end;

constructor TMPanel.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Name:='MainPanel';
  Height:=fieldheight;
  Align:=alTop;
  BevelInner:=bvNone;
  BevelOuter:=bvNone;
  ParentCtl3D:=false;
  Ctl3D:=false;
  BorderStyle:=bsNone;
  Caption:='';
  Visible:=True;
  currindex:=0;
  FItems:=TStringList.Create;
  FTypes:=TStringList.Create;
  FValues:=TStringList.Create;
  Edit:=TDETextBox.Create(self);
//  Edit.BorderStyle:=bsNone;
  Edit.Left:=width div 2+1;
  Edit.Top:=2;
  Edit.Width:=width div 2;
  Edit.Height:=fieldheight-2;
  Edit.Visible:=false;
  Edit.Parent:=self;
end;

destructor TMPanel.Destroy;
begin
  FItems.Free;
  FTypes.Free;
  FValues.Free;
  Edit.Free;
  inherited Destroy;
end;

procedure TMPanel.DrawItem(i:integer;state:integer);
begin
      canvas.Pen.Color:=clSilver;
      canvas.Brush.Color:=clBtnFace;
      canvas.Font.Color:=clBlack;
      canvas.TextOut(4,(i*fieldheight)+1,FItems.strings[i]);
      canvas.Font.Color:=clNavy;
      canvas.TextOut(width div 2+4,(i*fieldheight)+1,FValues.strings[i]);
//      canvas.Pen.Color:=clSilver;
//      canvas.MoveTo(0,fieldheight*i);
//      canvas.LineTo(width,fieldheight*i);
      case state of
      0:
      begin
      canvas.Pen.Color:=clBtnFace;
      canvas.MoveTo(0,i*fieldheight+1);
      canvas.LineTo(width,i*fieldheight+1);
      canvas.Pen.Color:=clSilver;
      canvas.MoveTo(0,i*fieldheight);
      canvas.LineTo(width,i*fieldheight);
      canvas.Pen.Color:=clSilver;
      canvas.MoveTo(0,i*fieldheight+fieldheight);
      canvas.LineTo(width,i*fieldheight+fieldheight);
      canvas.Pen.Color:=clBtnFace;
      canvas.MoveTo(0,i*fieldheight+fieldheight-1);
      canvas.LineTo(width,i*fieldheight+fieldheight-1);
      end;
      1:
      begin
      canvas.Pen.Color:=clBlack;
      canvas.MoveTo(0,i*fieldheight+1);
      canvas.LineTo(width,i*fieldheight+1);
      canvas.MoveTo(0,i*fieldheight);
      canvas.LineTo(width,i*fieldheight);
      canvas.Pen.Color:=clWhite;
      canvas.MoveTo(0,i*fieldheight+fieldheight);
      canvas.LineTo(width,i*fieldheight+fieldheight);
      canvas.MoveTo(0,i*fieldheight+fieldheight-1);
      canvas.LineTo(width,i*fieldheight+fieldheight-1);
      end;
      end;
      canvas.Pen.Color:=clSilver;
      canvas.MoveTo(width div 2,0);
      canvas.LineTo(width div 2,height);
      canvas.Pen.Color:=clWhite;
      canvas.MoveTo(width div 2+1,0);
      canvas.LineTo(width div 2+1,height);
end;
procedure TMPanel.Paint;
var i:integer;
begin
  inherited Paint;
  if FItems.Count>0 then
  begin
    height:=(fieldheight*FItems.Count)+2;
//    Edit.Visible:=false;
    for i:=0 to FItems.Count-1 do
    begin
//      canvas.Pen.Color:=clSilver;
//      canvas.Brush.Color:=clBtnFace;
//      canvas.TextOut(4,(i*fieldheight)+1,copy(FItems.strings[i],1,pos(' ',FItems.strings[i])-1));
//      canvas.Pen.Color:=clSilver;
//      canvas.MoveTo(width div 2,0);
//      canvas.LineTo(width div 2,height);
//      canvas.Pen.Color:=clWhite;
//      canvas.MoveTo(width div 2+1,0);
//      canvas.LineTo(width div 2+1,height);
//      canvas.Pen.Color:=clSilver;
//      canvas.MoveTo(0,fieldheight*i);
//      canvas.LineTo(width,fieldheight*i);
        if i=currindex then
        begin
          DrawItem(i,1);
          Edit.Left:=width div 2;
          Edit.Top:=i*fieldheight+1;
          Edit.Width:=width div 2;
          Edit.Height:=fieldheight-2;
          Edit.Text:=FValues.strings[i];
          case (strtoptype(FTypes.strings[i])) of
          ptString:Edit.ControlType:=ctEditBox;
          ptButton:Edit.ControlType:=ctEllipseBox;
          ptComboBox:Edit.ControlType:=ctComboBox;
          end;
          Edit.Visible:=true;
        end else DrawItem(i,0);
    end;
{
      canvas.Pen.Color:=clBtnFace;
      canvas.Brush.Color:=clBtnFace;
      canvas.FillRect(Rect(0,(FItems.Count-1*fieldheight),width,fieldheight)-1);
      canvas.Pen.Color:=clSilver;
      canvas.Brush.Color:=clBtnFace;
      canvas.TextOut(4,(FItems.Count-1*fieldheight)+1,copy(FItems.strings[FItems.Count-1],1,pos(' ',FItems.strings[FItems.Count-1])-1));
      canvas.Pen.Color:=clSilver;
      canvas.MoveTo(width div 2,0);
      canvas.LineTo(width div 2,height);
      canvas.Pen.Color:=clWhite;
      canvas.MoveTo(width div 2+1,0);
      canvas.LineTo(width div 2+1,height);
      canvas.Pen.Color:=clSilver;
      canvas.MoveTo(0,fieldheight*(FItems.Count-1));
      canvas.LineTo(width,fieldheight*(FItems.Count-1));
}
  end;
end;

procedure TMPanel.InsertProperty(item:integer;pname:string;ptype:tproptype;value:string);
begin
  FItems.Insert(item,pname);
  FItems.Insert(item,ptypetostr(ptype));
  FItems.Insert(item,value);
  Paint;
end;

procedure TMPanel.AddProperty(pname:string;ptype:tproptype;value:string);
begin
  FItems.Add(pname);
  FTypes.Add(ptypetostr(ptype));
  FValues.Add(value);
  Paint;
end;

function TMPanel.GetPropertyValue(pname:string):string;
var i:integer;
begin
 for i:=1 to FItems.Count do
 begin
   if UpperCase(FItems[i])=UpperCase(pname) then Result:=FValues[i];
 end;
end;


procedure TMPanel.ClearPropertyes;
begin
  FItems.Clear;
  FTypes.Clear;
  FValues.Clear;
  Paint;
end;

procedure TMPanel.MouseDown(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer);
var i:integer;
begin
  inherited MouseDown(Button,Shift,x,y);
  Edit.Visible:=false;
  DrawItem(oldindex,0);
  FValues.strings[oldindex]:=Edit.Text;
  i:=Trunc(y/fieldheight);
  DrawItem(i,1);
  oldindex:=i;
end;
procedure TMPanel.MouseMove(Shift: TShiftState; X, Y: Integer);
var i:integer;
begin
  inherited MouseMove(Shift,x,y);
  If ssLeft in shift then
  begin
    if oldindex<>i then
    begin
      DrawItem(oldindex,0);
//      FValues.strings[oldindex]:=Edit.Text;
      i:=Trunc(y/fieldheight);
      DrawItem(i,1);
      oldindex:=i;
    end;
  end;
end;
procedure TMPanel.MouseUp(Button: TMouseButton; Shift: TShiftState;
      X, Y: Integer);
var i:integer;
begin
  inherited MouseUp(Button,Shift,x,y);
  DrawItem(oldindex,0);
//  FValues.strings[oldindex]:=Edit.Text;
  i:=Trunc(y/fieldheight);
  currindex:=i;
  Edit.Left:=width div 2;
  Edit.Top:=i*fieldheight+1;
  Edit.Width:=width div 2;
  Edit.Height:=fieldheight-2;
  Edit.Text:=FValues.strings[i];
  case (strtoptype(FTypes.strings[i])) of
  ptString:Edit.ControlType:=ctEditBox;
  ptButton:Edit.ControlType:=ctEllipseBox;
  ptComboBox:Edit.ControlType:=ctComboBox;
  end;
  Edit.Visible:=true;
//  Edit.SetFocus;
//  Edit.SelectAll;
  DrawItem(oldindex,1);
  oldindex:=i;
end;

procedure Register;
begin
  RegisterComponents('Additional', [TPropertyBox]);
end;

end.
